package com.newlink.building.login.ui.fragments

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import com.newlink.building.login.R
import com.newlink.building.login.common.Module_Login_Constant
import com.newlink.building.login.databinding.FragmentPhoneRegisterBinding
import com.newlink.building.login.mvp.contract.Module_Login_RegisterContract
import com.newlink.building.login.ui.Module_Login_RegisterActivityNL
import com.newlink.building.common_base.base.BaseMvpFragment
import com.newlink.building.common_base.base.NL_OnActivityCallback
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.TYPE_REGISTER_SUCCESS
import com.newlink.building.common_base.ext.showToast
import com.newlink.building.common_base.model.bean.KitRegisterRequest
import com.newlink.building.common_base.model.bean.LoginResponseData
import com.newlink.building.common_base.model.bean.RegisterResultData
import com.newlink.building.common_base.model.bean.VerifyCodeRequest
import com.newlink.building.common_base.utils.countrycode.Base_CountryCodeSelectActivityNL
import com.newlink.building.utils.Module_Phone_CountdownWorker
import com.newlink.building.login.mvp.presenter.Module_Login_RegisterPresenter
import org.greenrobot.eventbus.EventBus

/**
 * @Author: xiaodong
 * @Date: 2024/12/11
 * @Description: 手机号注册界面，处理手机号、验证码输入、获取验证码倒计时以及设备注册的逻辑。
 */
class Module_Login_PhoneRegisterFragment : BaseMvpFragment<Module_Login_RegisterContract.View, Module_Login_RegisterContract.Presenter>(),
    Module_Login_RegisterContract.View {

    // 视图绑定实例
    private lateinit var binding: FragmentPhoneRegisterBinding

    // 从 Bundle 中获取的设备 JSON 数据
    private var deviceJsonData: String = ""

    // 倒计时工具
    private var countdownWorker: Module_Phone_CountdownWorker? = null

    // 倒计时时长，默认为 120 秒
    private val countDownDuration: Long = 120000L

    /**
     * Companion object 用于提供 Fragment 实例。
     */
    companion object {
        // Bundle 中用于传递设备数据的键
        private const val ARG_KIT_DEVICE_DATA: String = "kit_device_data"

        /**
         * 获取 PhoneRegisterFragment 的新实例。
         * @param json 设备数据的 JSON 字符串。
         * @return PhoneRegisterFragment 实例。
         */
        fun getInstance(json: String): Module_Login_PhoneRegisterFragment {
            val fragment = Module_Login_PhoneRegisterFragment()
            val bundle = Bundle().apply {
                putString(ARG_KIT_DEVICE_DATA, json)
            }
            fragment.arguments = bundle
            return fragment
        }
    }

    /**
     * 绑定布局文件并返回根视图。
     */
    override fun attachLayoutRes(): View {
        binding = FragmentPhoneRegisterBinding.inflate(layoutInflater)
        return binding.root
    }

    /**
     * 创建 Presenter 实例。
     */
    override fun createPresenter(): Module_Login_RegisterContract.Presenter {
        return Module_Login_RegisterPresenter()
    }

    /**
     * 初始化视图组件和设置监听器。
     */
    override fun initView(view: View) {
        deviceJsonData = requireArguments().getString(ARG_KIT_DEVICE_DATA, "") // 获取设备数据
        binding.tvCountryCode.text = countryCode // 设置默认国家码

        setupClickListeners()
        setupTextWatchers()
    }

    /**
     * 设置所有可点击视图的监听器。
     */
    private fun setupClickListeners() {
        // 切换到邮箱注册页面
        binding.tvSwitchEmail.setOnClickListener {
            (activity as? Module_Login_RegisterActivityNL)?.showFragment(Module_Login_Constant.Type.REGISTER_EMAIL, true)
        }

        // 选择国家码
        binding.tvCountryCode.setOnClickListener {
            navigateToCountryCodeSelection()
        }

        // 获取验证码按钮
        binding.btnVerityCode.setOnClickListener {
            handleGetVerifyCodeClick()
        }

        // 清除手机号输入框内容
        binding.ivPhoneNumClear.setOnClickListener {
            binding.etPhoneNumber.text?.clear()
        }

        // 提交注册按钮
        binding.btnSubmit.setOnClickListener {
            handleSubmitClick()
        }
    }

    /**
     * 设置所有 EditText 的文本变化监听器。
     */
    private fun setupTextWatchers() {
        binding.etPhoneNumber.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
            override fun afterTextChanged(p0: Editable?) {
                updateClearButtonState()
                updateSubmitButtonState()
            }
        })

        binding.etVerityCode.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
            override fun afterTextChanged(p0: Editable?) {
                updateSubmitButtonState()
            }
        })
    }

    /**
     * 导航到国家码选择页面。
     */
    private fun navigateToCountryCodeSelection() {
        val intent = Intent(requireContext(), Base_CountryCodeSelectActivityNL::class.java)
        (activity as? Module_Login_RegisterActivityNL)?.startActivityForResult(
            intent,
            object : NL_OnActivityCallback {
                @SuppressLint("SetTextI18n")
                override fun onActivityResult(resultCode: Int, data: Intent?) {
                    if (resultCode == 1_000_008) { // 假设 1_000_008 是成功的 resultCode
                        val defaultCountryCode = data?.getStringExtra("default_country_code")
                        if (!defaultCountryCode.isNullOrEmpty()) {
                            binding.tvCountryCode.text = defaultCountryCode
                            countryCode = defaultCountryCode // 更新本地存储的国家码
                        }
                    }
                }
            })
    }

    /**
     * 处理“获取验证码”按钮点击事件。
     * 进行手机号验证并请求发送验证码。
     */
    private fun handleGetVerifyCodeClick() {
        val phoneNumber = binding.etPhoneNumber.text.toString()

        if (phoneNumber.isEmpty()) {
            showToast(
                getString(
                    R.string.user_register_params_empty,
                    getString(R.string.user_verify_hint_phone)
                )
            )
            return
        }

        if (!isValidPhoneNumber(phoneNumber)) {
            showToast(getString(R.string.regex_phone_error_format))
            return
        }

        // 发送获取验证码请求
        mPresenter?.getVerifyCode(
            VerifyCodeRequest(
                area = binding.tvCountryCode.text.toString(),
                mobile = binding.etPhoneNumber.text.toString(),
                email = "", // 手机注册流程邮箱为空
                login = false, // 非重置密码流程
                userCategory = 1 // 用户类别，根据业务需求设置
            )
        )
    }

    /**
     * 处理“提交”按钮点击事件。
     * 组装设备注册请求并发送。
     */
    private fun handleSubmitClick() {
        // 原始代码中包含一些测试和注释掉的逻辑，此处只保留解析设备数据并提交的逻辑
        mPresenter?.kitRegister(parseDeviceRequest())
    }

    /**
     * 解析设备 JSON 数据并构建注册请求。
     * @return KitRegisterRequest 注册请求对象。
     */
    private fun parseDeviceRequest(): KitRegisterRequest {
        val devices = mPresenter?.getKitDeviceDataFromQrcode(deviceJsonData)
        return KitRegisterRequest(
            area = binding.tvCountryCode.text.toString(),
            mobile = binding.etPhoneNumber.text.toString(),
            code = binding.etVerityCode.text.toString(),
            devices = devices
        )
    }

    /**
     * 更新手机号输入框的清除按钮可见状态。
     */
    private fun updateClearButtonState() {
        binding.ivPhoneNumClear.visibility = if (binding.etPhoneNumber.text.isNullOrEmpty()) {
            View.INVISIBLE
        } else {
            View.VISIBLE
        }
    }

    /**
     * 更新提交按钮的启用状态。
     * 只有当手机号和验证码都不为空时，按钮才可用。
     */
    private fun updateSubmitButtonState() {
        binding.btnSubmit.isEnabled = binding.etPhoneNumber.text.toString().isNotEmpty() &&
                binding.etVerityCode.text.toString().isNotEmpty()
    }

    /**
     * 验证手机号格式是否符合要求。
     * @param phoneNumber 要验证的手机号码字符串。
     * @return 如果手机号码格式正确返回 true，否则返回 false。
     */
    private fun isValidPhoneNumber(phoneNumber: String): Boolean {
        // 原始代码中为 \d{4,}，表示至少4位数字。
        val phoneMatcher = "\\d{4,}".toRegex()
        return phoneNumber.matches(phoneMatcher)
    }

    /**
     * 初始化并启动验证码倒计时。
     */
    private fun startCountdownWorker() {
        if (countdownWorker == null) {
            countdownWorker = Module_Phone_CountdownWorker(countDownDuration).apply {
                setListener(countdownWorkerListener)
            }
        }
        countdownWorker?.start()
    }

    /**
     * 验证码倒计时监听器。
     */
    private val countdownWorkerListener = object : Module_Phone_CountdownWorker.CountdownListener {
        override fun onTick(millisUntilFinished: Long) {
            // 从大约 120s 开始显示，确保倒计时显示正确
            val seconds = (millisUntilFinished + 900) / 1000
            binding.btnVerityCode.text =
                String.format(getString(R.string.verify_code_timer), seconds)
        }

        override fun onFinish() {
            updateVerifyButtonState(true) // 倒计时结束，按钮可用
        }
    }

    /**
     * 更新获取验证码按钮及手机号输入框的状态。
     * @param isEnabled 如果为 true，则按钮和输入框可用；否则禁用。
     */
    private fun updateVerifyButtonState(isEnabled: Boolean) {
        if (isEnabled) {
            binding.btnVerityCode.text = getString(R.string.user_register_verify_code)
        }
        binding.btnVerityCode.isEnabled = isEnabled
        binding.etPhoneNumber.isEnabled = isEnabled
        binding.ivPhoneNumClear.visibility = if (isEnabled) View.VISIBLE else View.INVISIBLE
    }

    /**
     * 懒加载方法，当前未实现具体逻辑。
     */
    override fun lazyLoad() {
        // 无需额外的数据加载
    }

    /**
     * 当 Fragment 销毁时，停止倒计时并释放资源。
     */
    override fun onDestroy() {
        super.onDestroy()
        countdownWorker?.stop()
        countdownWorker = null
    }

    /*
     * 以下是 RegisterContract.View 接口的实现方法
     */

    /**
     * 注册成功回调。
     * 显示成功 Toast，发送注册成功事件，并跳转到注册成功页面。
     * @param data 注册结果数据。
     */
    override fun registerSuccess(data: RegisterResultData) {
        showToast(getString(R.string.user_register_success))
        EventBus.getDefault().post(
            MessageEvent(
                TYPE_REGISTER_SUCCESS,
                LoginResponseData(data.access_token, data.userId.toLong())
            )
        )
        (activity as? Module_Login_RegisterActivityNL)?.showFragment(Module_Login_Constant.Type.REGISTER_SUCCESS, true)
    }

    /**
     * 注册失败回调。
     * 显示失败 Toast。
     */
    override fun registerFail() {
        showToast(getString(R.string.user_register_failure))
    }

    /**
     * 获取验证码成功回调。
     * 显示成功 Toast，更新验证码按钮状态，并启动倒计时。
     * @param success 是否成功获取验证码。
     */
    override fun getVerifyCodeSuccess(success: Boolean) {
        showToast(getString(R.string.get_verify_code_success))
        updateVerifyButtonState(!success) // 如果成功，禁用按钮并开始倒计时；否则保持可用
        if (success) {
            startCountdownWorker()
        }
    }
}